//
//  TFPhotoBrowserDisplayCell.m
//  PhotoDemoProject
//
//  Created by TFAppleWork-Summer on 2017/2/7.
//  Copyright © 2017年 TFAppleWork-Summer. All rights reserved.
//

#import "TFPhotoBrowserDisplayCell.h"
//UI
#import "UIColor+TFPhoto.h"
#import "TFPhotoResourceHelper.h"
#import "TFPhotoDownloadView.h"

//工具类
#import "TFPhotoHandler.h"
#import <SDWebImage/SDWebImageDownloader.h>
#import <SDWebImage/SDImageCache.h>


static NSInteger kTFPhotoDisplayDownloadFailViewTag = 100;
static NSInteger kTFPhotoDisplayDownloadProgressViewTag = 101;

typedef NS_ENUM(NSUInteger, TFPhotoType) {
    TFPhotoTypePHAsset,///<相册PHAsset
    TFPhotoTypeURL,///<网络图片
    TFPhotoTypeString,///<本地图片
    TFPhotoTypeUrlString,///<网络图片地址
    TFPhotoTypeImage,///<UIImage对象
};

@interface TFPhotoBrowserDisplayCell ()

@property (nonatomic, strong, readwrite) TFPhotoScrollView *photoScrollView;

@property (nonatomic, assign) TFPhotoType photoType;

@property (nonatomic, strong) SDWebImageDownloadToken *downloadToken;

@property (nonatomic, strong) SDImageCache *imageCache;

@property (nonatomic, strong) SDWebImageDownloader *imageDownLoader;

@property (nonatomic, strong) UIImage *showImage;

@property (nonatomic, assign) PHImageRequestID iCloudRequestId;

@end

@implementation TFPhotoBrowserDisplayCell

@synthesize photo = _photo;
@synthesize image = _image;
@synthesize photoScrollView = _photoScrollView;
@synthesize videoPlayView = _videoPlayView;
@synthesize indexPath = _indexPath;
@synthesize delegate = _delegate;
@synthesize isLoading = _isLoading;

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        _iCloudRequestId = 0;
        self.contentView.backgroundColor = [UIColor blackColor];
        [self.contentView addSubview:self.photoScrollView];
        //添加约束
        _photoScrollView.translatesAutoresizingMaskIntoConstraints = NO;
        NSDictionary *viewDic = @{@"photoScrollView":self.photoScrollView};
        [NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[photoScrollView]|" options:0 metrics:nil views:viewDic]];
        [NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[photoScrollView]|" options:0 metrics:nil views:viewDic]];
    }
    return self;
}

- (UIImage *)image {
    return self.photoScrollView.image;
}

- (void)setPhoto:(id)photo {
    _photo = photo;
    _photoType = TFPhotoTypeString;
    if ([_photo isKindOfClass:[PHAsset class]]) {
        _photoType = TFPhotoTypePHAsset;
        [self p_cachePhotoWithCacheKey:nil];
    }
    else if ([_photo isKindOfClass:[NSURL class]]) {
        _photoType = TFPhotoTypeURL;
    }
    else if ([_photo isKindOfClass:[NSString class]]) {
        NSString *photoString = (NSString *)_photo;
        if ([photoString hasPrefix:@"http://"]|[photoString hasPrefix:@"https://"]) {
            _photoType = TFPhotoTypeUrlString;
        }
        else {
            _photoType = TFPhotoTypeString;
            [self p_cachePhotoWithCacheKey:photoString];
        }
    }
    else if ([_photo isKindOfClass:[UIImage class]]) {
        _photoType = TFPhotoTypeImage;
        NSTimeInterval currentTimeSp = [[NSDate date] timeIntervalSince1970];
        NSString *cacheKey = [NSString stringWithFormat:@"%zd",(NSInteger)currentTimeSp];
        [self p_cachePhotoWithCacheKey:cacheKey];
    }
}

- (void)loadPhoto {
    if ([self.delegate respondsToSelector:@selector(photoBrowserDisplayCellDidLoadPhoto:)]) {
        [self.delegate photoBrowserDisplayCellDidLoadPhoto:self];
    }
    [self p_clearDownloadViews];
    switch (_photoType) {
        case TFPhotoTypePHAsset:
        {
            typeof(self) __weak weakSelf = self;
            [[TFPhotoHandler sharedHandler] getOriginalImageWithAsset:_photo synchronous:YES progressHandler:nil resultHandler:^(UIImage *image, NSDictionary *info) {
                if ([info[PHImageResultIsInCloudKey] boolValue]) {
                    [weakSelf p_requestImageFromICloud];
                }
                else {
                    weakSelf.photoScrollView.image = image;
                    if ([weakSelf.delegate respondsToSelector:@selector(photoBrowserDisplayCellDidFinishLoadPhoto:)]) {
                        [weakSelf.delegate photoBrowserDisplayCellDidFinishLoadPhoto:weakSelf];
                    }
                }
            }];
        }
            break;
        case TFPhotoTypeURL:case TFPhotoTypeUrlString: {
            if (_photoType==TFPhotoTypeUrlString) {
                [self p_downLoadImageWithURL:[NSURL URLWithString:self.photo]];
            }
            else {
                [self p_downLoadImageWithURL:self.photo];
            }
        }
            break;
        case TFPhotoTypeString:case TFPhotoTypeImage: {
            self.photoScrollView.image = self.showImage;
        }
            break;
        default:
            break;
    }
    
}

- (void)p_loadVideoWithAsset:(AVAsset *)asset {
    
    AVPlayerItem *item = [AVPlayerItem playerItemWithAsset:asset];
    [self.videoPlayView.player replaceCurrentItemWithPlayerItem:item];
}

- (void)p_requestImageFromICloud {
    typeof(self) __weak weakSelf = self;
    TFPhotoDownloadView *downloadView = [self p_showDownloadView];
    _iCloudRequestId = [[TFPhotoHandler sharedHandler] downLoadICloudImageWithAsset:_photo progressHandler:^(double progress, NSError * _Nullable error, BOOL * _Nonnull stop, NSDictionary * _Nullable info) {
        if (!error) {
            dispatch_async(dispatch_get_main_queue(), ^{
                downloadView.progress = progress;
            });
        }
        
    } resultHandler:^(UIImage *image, NSDictionary *info) {
        //清空requestID
        weakSelf.iCloudRequestId = 0;
        dispatch_async(dispatch_get_main_queue(), ^{
            if (image) {
                [weakSelf p_clearDownloadViews];
                weakSelf.photoScrollView.image = image;
                if ([weakSelf.delegate respondsToSelector:@selector(photoBrowserDisplayCellDidFinishLoadPhotoFromICloud:)]) {
                    [weakSelf.delegate photoBrowserDisplayCellDidFinishLoadPhotoFromICloud:weakSelf];
                }
            }
            else {
                [downloadView removeFromSuperview];
                [weakSelf p_showDownloadFailedView];
            }
        });

        
    }];
}

- (void)p_requestVideoFromICloud {
    typeof(self) __weak weakSelf = self;
    TFPhotoDownloadView *downloadView = [self p_showDownloadView];
    _iCloudRequestId = [[TFPhotoHandler sharedHandler] downLoadICloudVideoWithPHAsset:_photo progressHandler:^(double progress, NSError * _Nullable error, BOOL * _Nonnull stop, NSDictionary * _Nullable info) {
        if (!error) {
            dispatch_async(dispatch_get_main_queue(), ^{
                downloadView.progress = progress;
            });
        }
    } resultHandler:^(AVAsset * _Nullable asset, AVAudioMix * _Nullable audioMix, NSDictionary * _Nullable info) {
        //清空requestID
        weakSelf.iCloudRequestId = 0;
        dispatch_async(dispatch_get_main_queue(), ^{
            if (asset) {
                [weakSelf p_clearDownloadViews];
                //加载视频
                [weakSelf p_loadVideoWithAsset:asset];
                if ([weakSelf.delegate respondsToSelector:@selector(photoBrowserDisplayCellDidFinishLoadPhotoFromICloud:)]) {
                    [weakSelf.delegate photoBrowserDisplayCellDidFinishLoadPhotoFromICloud:weakSelf];
                }
            }
            else {
                [downloadView removeFromSuperview];
                [weakSelf p_showDownloadFailedView];
            }

        });
       
    }];
}

- (void)p_downLoadImageWithURL:(NSURL *)url {
    NSString *cacheKey = url.absoluteString;
    UIImage *cacheImage = [self.imageCache imageFromCacheForKey:cacheKey];
    if (cacheImage) {
        [self p_handleDownLoadImageFinishWithImage:cacheImage cacheKey:cacheKey needCache:NO];
    }
    else {
        [self p_requestImageWithUrl:url];
    }
}

- (void)p_requestImageWithUrl:(NSURL *)url {
    typeof(self) __weak weakSelf = self;
    NSString *cacheKey = url.absoluteString;
    TFPhotoDownloadView *downloadView = [self p_showDownloadView];
    self.downloadToken = [self.imageDownLoader downloadImageWithURL:url options:SDWebImageDownloaderLowPriority progress:^(NSInteger receivedSize, NSInteger expectedSize, NSURL * _Nullable targetURL) {
        float progress = receivedSize/(float)expectedSize;
        dispatch_async(dispatch_get_main_queue(), ^{
            downloadView.progress = progress;
        });
    } completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, BOOL finished) {
        dispatch_async(dispatch_get_main_queue(), ^{
            if (error) {
                [downloadView removeFromSuperview];
                [weakSelf p_showDownloadFailedView];
            }
            else {
                [weakSelf p_clearDownloadViews];
                [weakSelf p_handleDownLoadImageFinishWithImage:image cacheKey:cacheKey needCache:YES];
            }
        });
    }];
}

- (TFPhotoDownloadView *)p_showDownloadView {
    TFPhotoDownloadView *downloadView = [[TFPhotoDownloadView alloc] initWithFrame:CGRectMake(0.0, 0.0, 50.0, 50.0)];
    downloadView.progress = 0.0;
    downloadView.tag = kTFPhotoDisplayDownloadProgressViewTag;
    downloadView.center = self.contentView.center;
    [self.contentView addSubview:downloadView];
    return downloadView;
}

- (void)p_showDownloadFailedView {
    //添加加载失败视图
    UIView *downloadFailView = [self p_photoDisplayCellDownloadFailView];
    [downloadFailView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(loadPhoto)]];
    downloadFailView.tag = kTFPhotoDisplayDownloadFailViewTag;
    downloadFailView.frame = self.contentView.bounds;
    [self.contentView addSubview:downloadFailView];
}

- (UIView *)p_photoDisplayCellDownloadFailView {
    UIView *downloadFailView = [[UIView alloc] init];
    
    //添加subView
    UIImageView *failImageView = [[UIImageView alloc] initWithImage:[TFPhotoResourceHelper imageNamed:@"photo_download_fail"]];
    [downloadFailView addSubview:failImageView];
    
    UILabel *detailLabel = [[UILabel alloc] init];
    detailLabel.text = [TFPhotoResourceHelper localizedStringWithKey:@"图片加载失败，请点击重试"];
    detailLabel.textColor = [UIColor tfPhoto_hexColorWith:@"696969"];
    detailLabel.font = [UIFont systemFontOfSize:14];
    [downloadFailView addSubview:detailLabel];
    
    //添加约束
    failImageView.translatesAutoresizingMaskIntoConstraints = NO;
    detailLabel.translatesAutoresizingMaskIntoConstraints = NO;
    
    [NSLayoutConstraint constraintWithItem:failImageView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:downloadFailView attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0.0].active = YES;
    [NSLayoutConstraint constraintWithItem:failImageView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:downloadFailView attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:-30.0].active = YES;
    [NSLayoutConstraint constraintWithItem:detailLabel attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:downloadFailView attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0.0].active = YES;
    [NSLayoutConstraint constraintWithItem:detailLabel attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:failImageView attribute:NSLayoutAttributeBottom  multiplier:1.0 constant:6.0].active = YES;
    return downloadFailView;
}



- (void)p_handleDownLoadImageFinishWithImage:(UIImage *)image cacheKey:(NSString *)cacheKey needCache:(BOOL)needCache {
    self.photoScrollView.image = image;
    if ([self.delegate respondsToSelector:@selector(photoBrowserDisplayCellDidFinishLoadPhoto:)]) {
        [self.delegate photoBrowserDisplayCellDidFinishLoadPhoto:self];
    }
    //缓存图片
    if (needCache) {
        [self p_cachePhotoWithCacheKey:cacheKey];
    }
}

- (void)p_clearDownloadViews {
    UIView *downloadFailView = [self.contentView viewWithTag:kTFPhotoDisplayDownloadFailViewTag];
    if (downloadFailView) {
        [downloadFailView removeFromSuperview];
    }
    UIView *downloadProgressView = [self.contentView viewWithTag:kTFPhotoDisplayDownloadProgressViewTag];
    if (downloadProgressView) {
        [downloadProgressView removeFromSuperview];
    }
}

- (void)clearPhoto {
    switch (_photoType) {
        case TFPhotoTypePHAsset:
        {
            [[TFPhotoHandler sharedHandler] clearCacheImagesWithAssets:@[_photo] size:PHImageManagerMaximumSize];
        }
            break;
        case TFPhotoTypeURL: case TFPhotoTypeUrlString: {
            //取消下载
            [self.downloadToken cancel];
            //清空缓存
            [self.imageCache removeImageForKey:self.downloadToken.url.absoluteString fromDisk:NO withCompletion:nil];
        }
            break;
        case TFPhotoTypeImage: case TFPhotoTypeString: {
            _showImage = nil;
        }
            break;
        default:
            break;
    }
    self.photoScrollView.image = nil;
    if ([self.delegate respondsToSelector:@selector(photoBrowserDisplayCellDidClearPhoto:)]) {
        [self.delegate photoBrowserDisplayCellDidClearPhoto:self];
    }
}

- (void)clearAllCachedPhotosAndCancelDownloadingSession {
    [self.imageDownLoader cancelAllDownloads];
    [self.imageCache clearMemory];
    _imageCache = nil;
    if (_iCloudRequestId!=0) {
        [[TFPhotoHandler sharedHandler] cancelICloudDownloadWith:_iCloudRequestId];
    }
}

#pragma mark - photo handler actions.

- (void)p_cachePhotoWithCacheKey:(NSString *)cacheKey {
    
    switch (_photoType) {
        case TFPhotoTypePHAsset:
        {
            [[TFPhotoHandler sharedHandler] cacheThumbnailImageWithAssets:@[_photo] size:PHImageManagerMaximumSize];
        }
            break;
        case TFPhotoTypeURL: case TFPhotoTypeUrlString: {
            [self.imageCache storeImage:self.photoScrollView.image forKey:cacheKey completion:nil];
        }
            break;
        case TFPhotoTypeImage:case TFPhotoTypeString: {
            
            [self.imageCache storeImage:self.showImage forKey:cacheKey toDisk:NO completion:nil];
        }
            break;
        default:
            break;
    }
}

#pragma mark - lazy load.

- (TFPhotoScrollView *)photoScrollView {
    if (!_photoScrollView) {
        _photoScrollView = [[TFPhotoScrollView alloc] initWithFrame:[UIScreen mainScreen].bounds];
    }
    return _photoScrollView;
}

- (SDImageCache *)imageCache {
    if (!_imageCache) {
        _imageCache = [SDImageCache sharedImageCache];
    }
    return _imageCache;
}

- (SDWebImageDownloader *)imageDownLoader {
    if (!_imageDownLoader) {
        _imageDownLoader = [[SDWebImageDownloader alloc] initWithConfig:[SDWebImageDownloaderConfig defaultDownloaderConfig]];
        _imageDownLoader.config.downloadTimeout = 60.0*5;
    }
    return _imageDownLoader;
}

- (UIImage *)showImage {
    if (!_showImage) {
        switch (_photoType) {
            case TFPhotoTypeString:
            {
                _showImage = [UIImage imageNamed:self.photo];
                if (!_showImage) {
                    _showImage = [UIImage imageWithContentsOfFile:self.photo];
                }
                NSAssert(_showImage, @"The path or name of this photo is not right.");
            }
                break;
            case TFPhotoTypeImage: {
                _showImage = self.photo;
            }
                break;
            default:
                break;
        }
    }
    return _showImage;
}



- (void)dealloc {
    [self clearAllCachedPhotosAndCancelDownloadingSession];
    NSLog(@"\n******************************************\n %s---line:%d \n******************************************",__func__,__LINE__);
}


@end
